#include "settings.hpp"
#include "exceptions.hpp"

#include <cassert>

namespace hms
{

void Settings::setLogger(){
	assert( !m_logger );
	m_logger = log::getLogger();
}

auto Settings::logger() const -> log::logger&{
	assert(m_logger);
	return *m_logger;
}

auto Settings::caseName() const -> const std::string& {
	assert( !m_caseName.empty() );
	return m_caseName;
}
void Settings::caseName( std::string&& arg ){
	assert( !arg.empty() );
	m_caseName = std::move(arg);
}



const fs::path& Settings::path( Path name ) const {
	const fs::path& pRef { m_paths[static_cast<int>(name)] };
	assert( !pRef.empty() && "Path not set!" );
	return pRef;
}
void Settings::path( Path name, fs::path&& p ){
	m_paths[static_cast<int>(name)] = std::move(p);
}

const fs::path& Settings::caseDir() const {
	return path(Path::caseDir);
}

const fs::path& Settings::vtkFilePath() const {
	return path(Path::vtkFile);
}
auto Settings::vtkFilePath() -> fs::path& {
	return const_cast<fs::path&>( path(Path::vtkFile) );
}

const fs::path& Settings::bindingFilePath() const {
	return path(Path::bindingFile);
}

const fs::path& Settings::boundaryPath() const {
	return path(Path::boundaryFile);
}

const fs::path& Settings::constFieldsPath() const {
	return path(Path::constFields);
}

const fs::path& Settings::sourceFieldsPath() const {
	return path(Path::sourceFields);
}

#define SETTINGS_ACCESSORS(TYPE, NAME) \
void Settings::NAME( TYPE&& arg ){ m_##NAME = std::move(arg); } \
auto Settings::NAME() -> TYPE& { \
	assert( m_##NAME.isValid() ); \
	return m_##NAME; \
} \
auto Settings::NAME() const -> const TYPE& { \
	assert( m_##NAME.isValid() ); \
	return m_##NAME; \
}

SETTINGS_ACCESSORS(MeshGenSettings, meshGen)
SETTINGS_ACCESSORS(TimeSettings, time)
SETTINGS_ACCESSORS(SWESettings, swe)
SETTINGS_ACCESSORS(BenchmarkSettings, benchmark)
SETTINGS_ACCESSORS(ImportSettings, import)
SETTINGS_ACCESSORS(ExportSettings, exportSettings)

#undef SETTINGS_ACCESSORS



void Settings::probes( std::vector<ProbeSettings>&& ps ){
	if ( !ps.empty() ){
		m_probes = std::move(ps);
		m_probesExist = true;
	}
}
std::vector<ProbeSettings>& Settings::probes() {
	assert( !(m_probes.empty() && m_probesExist) );
	return m_probes;
}

} // namespace hms
